﻿window.bookApp = window.bookApp || {};

window.bookApp.datacontext = (function () {

    var datacontext = {
        getBooks: getBooks,
        createBook: createBook,
        saveNewBook: saveNewBook,
        saveChangedBook: saveChangedBook,
        deleteBook: deleteBook
    };

    return datacontext;

    function getBooks(booksObservable, errorObservable) {
        return ajaxRequest("get", bookUrl())
            .done(getSucceeded)
            .fail(getFailed);

        function getSucceeded(data) {
            var mappedBooks = $.map(data, function (book) { return new createBook(book); });
            booksObservable(mappedBooks);
        }

        function getFailed() {
            errorObservable("Error retrieving book lists.");
        }
    }
    function createBook(data) {
        return new datacontext.book(data); // Book is injected by book.model.js
    }
    function saveNewBook(book) {
        clearErrorMessage(book);
        return ajaxRequest("post", bookUrl(), book)
            .done(function (result) {
                book.bookId = result.bookId;
                book.userId = result.userId;
            })
            .fail(function () {
                book.errorMessage("Error adding a new book list.");
            });
    }
    function deleteBook(book) {
        return ajaxRequest("delete", bookUrl(book.bookId))
            .fail(function () {
                book.errorMessage("Error removing book list.");
            });
    }
    function saveChangedBook(book) {
        clearErrorMessage(book);
        return ajaxRequest("put", bookUrl(book.bookId), book, "text")
            .fail(function () {
                book.errorMessage("Error updating the book list title. Please make sure it is non-empty.");
            });
    }

    // Private
    function clearErrorMessage(entity) { entity.errorMessage(null); }
    function ajaxRequest(type, url, data, dataType) { // Ajax helper
        var options = {
            dataType: dataType || "json",
            contentType: "application/json",
            cache: false,
            type: type,
            data: data ? data.toJson() : null
        };
        var antiForgeryToken = $("#antiForgeryToken").val();
        if (antiForgeryToken) {
            options.headers = {
                'RequestVerificationToken': antiForgeryToken
            }
        }
        return $.ajax(url, options);
    }
    // routes
    function bookUrl(id) { return "/api/book/" + (id || ""); }
})();